import { InjectRepository } from '@nestjs/typeorm';
import { ProductEntity } from './entities/shop-products.entity';
import { Repository } from 'typeorm';
import { CreateProductDto, QueryProductDto, UpdateProductDto } from './dto/shop-product.dto';
import { BadRequestException } from '@nestjs/common';
import { CategoryEntity } from '../categories/entities/shop-category.entity';
import { ResultData } from 'src/common/utils/result';
import { UpdateCategoryDto } from '../categories/dto/category.dto';

export class ProductService {
  constructor(
    @InjectRepository(ProductEntity)
    private readonly productRepo: Repository<ProductEntity>,
    @InjectRepository(CategoryEntity)
    private readonly categoryRepo: Repository<CategoryEntity>,
  ) {}

  async create(data: CreateProductDto) {
    const { categoryId, ...rest } = data;
    if (!categoryId) {
      throw new BadRequestException('请选择商品分类');
    }
    const category = await this.categoryRepo.findOne({ where: { id: categoryId } });

    await this.productRepo.save({ ...rest, category });
    return ResultData.ok();
  }

  async findOne(id: number) {
    const product = await this.productRepo.findOneBy({ id });
    return ResultData.ok(product);
  }

  async findAll(name?: string) {
    const entity = this.productRepo.createQueryBuilder('product');
    if (name) {
      entity.andWhere(`product.name LIKE "%${name}%"`);
    }
    const list = await entity.getMany();
    return ResultData.ok(list);
  }

  async findList(query: QueryProductDto) {
    const entity = this.productRepo.createQueryBuilder('product');
    const { pageSize, pageNum, name, categoryId } = query;
    if (name) {
      entity.andWhere(`product.name LIKE "%${name}%"`);
    }
    if (categoryId) {
      entity.andWhere(`product.categoryId = :categoryId`, { categoryId });
    }
    if (pageSize && pageNum) {
      entity.skip(pageSize * (pageNum - 1)).take(pageSize);
    }
    const [list, total] = await entity.getManyAndCount();
    return ResultData.ok({
      list,
      total,
    });
  }

  async update(data: UpdateProductDto) {
    const { id, categoryId, ...rest } = data;
    let category: CategoryEntity | null = null;
    const product = await this.productRepo.findOne({ where: { id }, relations: ['category'] });
    category = await this.categoryRepo.findOne({ where: { id: product.category.id } });
    if (categoryId) {
      category = await this.categoryRepo.findOne({ where: { id: categoryId } });
    }
    this.productRepo.update(id, { ...rest, category });
    return ResultData.ok();
  }

  async remove(id: number) {
    const product = await this.productRepo.findOne({ where: { id } });
    this.productRepo.remove(product);
    return ResultData.ok();
  }
}
